package com.patentbackend.patentmanage.controller;

import com.patentbackend.patentmanage.dto.PatentDTO;
import com.patentbackend.patentmanage.entity.Patent;
import com.patentbackend.patentmanage.service.PatentService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.IOException;
import java.util.List;

@RestController
@RequestMapping("/api/patents")
public class PatentController {

    private final PatentService patentService;

    public PatentController(PatentService patentService) {
        this.patentService = patentService;
    }

    @GetMapping
    public ResponseEntity<Page<Patent>> getAllPatents(Pageable pageable) {
        return ResponseEntity.ok(patentService.findAll(pageable));
    }

    @GetMapping("/search")
    public ResponseEntity<Page<Patent>> searchPatents(
            @RequestParam String keyword,
            Pageable pageable
    ) {
        return ResponseEntity.ok(patentService.search(keyword, pageable));
    }

    @GetMapping("/{id}")
    public ResponseEntity<Patent> getPatentById(@PathVariable Long id) {
        return patentService.findById(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }

    @PostMapping
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<Patent> createPatent(@Valid @RequestBody PatentDTO patentDTO) {
        Patent patent = patentService.createPatent(patentDTO);
        return ResponseEntity.status(HttpStatus.CREATED).body(patent);
    }

    @PutMapping("/{id}")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<Patent> updatePatent(
            @PathVariable Long id,
            @Valid @RequestBody PatentDTO patentDTO
    ) {
        if (!patentService.existsById(id)) {
            return ResponseEntity.notFound().build();
        }
        Patent updatedPatent = patentService.updatePatent(id, patentDTO);
        return ResponseEntity.ok(updatedPatent);
    }

    @DeleteMapping("/{id}")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<Void> deletePatent(@PathVariable Long id) {
        if (!patentService.existsById(id)) {
            return ResponseEntity.notFound().build();
        }
        patentService.deletePatent(id);
        return ResponseEntity.noContent().build();
    }

    @PostMapping("/{id}/upload-file")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<?> uploadFile(
            @PathVariable Long id,
            @RequestParam("file") MultipartFile file,
            @RequestParam("fileType") String fileType
    ) throws IOException {
        if (!patentService.existsById(id)) {
            return ResponseEntity.notFound().build();
        }
        String filePath = patentService.uploadPatentFile(id, file, fileType);
        return ResponseEntity.ok(filePath);
    }

    @GetMapping("/download/{filePath:.+}")
    @PreAuthorize("hasRole('INTERNAL')")
    public ResponseEntity<byte[]> downloadFile(@PathVariable String filePath) throws IOException {
        byte[] fileContent = patentService.downloadFile(filePath);

        String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", fileName);

        return new ResponseEntity<>(fileContent, headers, HttpStatus.OK);
    }

    @GetMapping("/annual-fee-reminders")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<List<Patent>> getAnnualFeeReminders() {
        List<Patent> reminders = patentService.getAnnualFeeReminders();
        return ResponseEntity.ok(reminders);
    }
}
